/*
    需求:
        创建两个ROS节点，服务器和客户端，
        客户端可以向服务器发送目标数据N（一个整型数据）
        服务器会计算1到N之间所有整数的和，这是一个循环累加的过程，返回给客户端，
        这是基于请求响应模式的，
        又已知服务器从接收到请求到产生响应是一个耗时操作，每累加一次耗时0.1s，
        为了良好的用户体验，需要服务器在计算过程中，
        每累加一次，就给客户端响应一次百分比格式的执行进度，使用action实现。

    流程:
        1.包含头文件;
        2.初始化ROS节点;
        3.创建NodeHandle;
        4.创建action服务对象;
        5.处理请求,产生反馈与响应;
        6.spin().

*/

#include "ros/ros.h"
#include "actionlib/server/simple_action_server.h"
#include "demo01_action/AddIntsAction.h"

typedef actionlib::SimpleActionServer<demo01_action::AddIntsAction> Server;

void cb(const demo01_action::AddIntsGoalConstPtr &goalPtr, Server *server)
{
    // a.解析请求的参数
    int goal_data = goalPtr->num;
    ROS_INFO("客户端提交的数据:%d", goal_data);
    // b.产生连续反馈
    ros::Rate rate(10); //计算一次耗时0.1秒
    int sum = 0;
    for (size_t i = 1; i <= goal_data; i++)
    {
        sum += i;
        rate.sleep();
        //产生反馈
        demo01_action::AddIntsFeedback fb;
        fb.progress_bar = i / (double)goal_data;
        server->publishFeedback(fb);
    }
    // c.执行结束时返回结果
    demo01_action::AddIntsResult r;
    r.result = sum;
    server->setSucceeded(r);
}

int main(int argc, char *argv[])
{
    // ros节点初始化
    setlocale(LC_ALL, "");
    ros::init(argc, argv, "addints_server");
    ros::NodeHandle nh;
    //创建action server对象
    // SimpleActionServer(
    //     ros::NodeHandle n,
    //     std::string name,
    //     boost::function<void (const demo01_action::AddIntsGoalConstPtr &)> execute_callback,
    //     bool auto_start)
    Server server(nh, "addints", boost::bind(cb, _1, &server), false);
    server.start();
    ROS_INFO("服务启动......");
    ros::spin();
    return 0;
}
